package com.explorex.infra.puma.gateway.netty.ws.utils;

import com.explorex.infra.puma.gateway.netty.common.SocketAttributeKeyConst;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.ssl.SslHandler;
import org.apache.commons.lang3.StringUtils;

import java.net.InetSocketAddress;

/**
 * @author: JacceYang
 * @createTime: 2022/07/14 8:43 下午
 * @description: WebSocket 相关的工具类
 */
public class SocketUtil {
    private static final String IP_LINK_TEMPLATE = "%s_%s_%s_%s";

    private static volatile String localIpCache=null;

    public static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) {
        return getWebSocketLocation(cp.get(SslHandler.class) != null, req, path);
    }

    public static String getWebSocketLocation(boolean bSSL, HttpRequest req, String path) {
        String protocol = "ws";
        if (bSSL) {
            protocol = "wss";
        }
        return protocol + "://" + req.headers().get(HttpHeaderNames.HOST) + path;
    }

    public static int getRemotePort(HttpHeaders httpHeaders, Channel channel){
        assert httpHeaders != null;

        String xForwardFor = httpHeaders.get("X-Forwarded-For");
        if (StringUtils.isNotBlank(xForwardFor)) {
            String[] split = xForwardFor.split(",");
            // X-Forwarded-For 格式为 client, proxy1, proxy2, 取第一个
            return Integer.valueOf(split[1].trim());
        }

        InetSocketAddress remoteAddress = channel.attr(SocketAttributeKeyConst.ATTR_REMOTE_ADDR).get();
        if (remoteAddress == null) {
            remoteAddress = (InetSocketAddress) channel.remoteAddress();
        }
        return remoteAddress.getPort();
    }
    public static String getRemoteIp(HttpHeaders httpHeaders, Channel channel) {
        assert httpHeaders != null;

        String xForwardFor = httpHeaders.get("X-Forwarded-For");
        if (StringUtils.isNotBlank(xForwardFor)) {
            String[] split = xForwardFor.split(",");
            // X-Forwarded-For 格式为 client, proxy1, proxy2, 取第一个
            return split[0].trim();
        }

        InetSocketAddress remoteAddress = channel.attr(SocketAttributeKeyConst.ATTR_REMOTE_ADDR).get();
        if (remoteAddress == null) {
            remoteAddress = (InetSocketAddress) channel.remoteAddress();
        }
        return remoteAddress.getAddress().getHostAddress();
    }

    public static String getLocalIp(Channel channel) {
        InetSocketAddress localAddress = (InetSocketAddress) channel.localAddress();
        if (localIpCache==null){
            localIpCache=localAddress.getAddress().getHostAddress();
        }
        return localIpCache;
    }

    public static String getLocalIpStatic(){
        return localIpCache;
    }

    public static String getIpLink(Channel channel) {
        InetSocketAddress localAddress = (InetSocketAddress) channel.localAddress();
        InetSocketAddress remoteAddress = channel.attr(SocketAttributeKeyConst.ATTR_REMOTE_ADDR).get();
        if (remoteAddress == null) {
            remoteAddress = (InetSocketAddress) channel.remoteAddress();
        }
        return String.format(IP_LINK_TEMPLATE, localAddress.getAddress().getHostAddress(), localAddress.getPort(), remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort());
    }
}
